package com.code2roc.jarmanage.util;

import com.alibaba.fastjson.JSONObject;
import com.code2roc.jarmanage.depoly.DepolyPlatform;
import com.code2roc.jarmanage.model.MachineBaseInfo;
import com.code2roc.jarmanage.model.MachineCPUInfo;
import com.code2roc.jarmanage.model.MachineDiskInfo;
import com.code2roc.jarmanage.model.MachineMemoryInfo;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.GlobalConfig;
import oshi.util.Util;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


public class MachineUtil {
    static final long GB = 1024 * 1024 * 1024;

    public static MachineBaseInfo getMachineBaseInfo() {
        Properties props = System.getProperties();
        MachineBaseInfo baseInfo = new MachineBaseInfo();
        baseInfo.setOsArch(props.getProperty("os.arch"));
        baseInfo.setOsName(props.getProperty("os.name"));
        baseInfo.setMachineName(IPUtil.getHostName());
        baseInfo.setMachineIp(IPUtil.getHostIp());
        return baseInfo;
    }

    public static MachineCPUInfo getMachineCPUInfo() {
        if (EnviromentUtil.getDepolyPlaform().equals(DepolyPlatform.Windows)) {
            GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true);
        }
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        CentralProcessor cpu = hal.getProcessor();
        MachineCPUInfo cpuInfo = new MachineCPUInfo();
        cpuInfo.setCpuNum(cpu.getLogicalProcessorCount());
        cpuInfo.setLoadRatio(ConvertUtil.convert2Double(cpu.getSystemCpuLoad(1000) * 100, 2));
        return cpuInfo;
    }

    public static int getCPUNum() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        CentralProcessor cpu = hal.getProcessor();
        return cpu.getLogicalProcessorCount();
    }

    public static MachineMemoryInfo getMachineMemoryInfo() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        Long totalPhysicalMemorySize = hal.getMemory().getTotal();
        Long freePhysicalMemorySize =  hal.getMemory().getAvailable();
        double totalMemory = 1.0 * totalPhysicalMemorySize / GB;
        double freeMemory = 1.0 * freePhysicalMemorySize / GB;
        double memoryUseRatio = 1.0 * (totalPhysicalMemorySize - freePhysicalMemorySize) / totalPhysicalMemorySize * 100;
        MachineMemoryInfo memoryInfo = new MachineMemoryInfo();
        memoryInfo.setTotal(ConvertUtil.convert2Double(totalMemory, 2));
        memoryInfo.setFree(ConvertUtil.convert2Double(freeMemory, 2));
        memoryInfo.setUseRatio(ConvertUtil.convert2Double(memoryUseRatio, 2));
        return memoryInfo;
    }

    public static double getTotalMemory() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        Long totalPhysicalMemorySize = hal.getMemory().getTotal();
        double totalMemory = 1.0 * totalPhysicalMemorySize / GB;
        return ConvertUtil.convert2Double(totalMemory, 2);
    }

    public static List<MachineDiskInfo> getMachineDiskInfo() {
        SystemInfo si = new SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        FileSystem fileSystem = os.getFileSystem();
        List<OSFileStore> fsArray = fileSystem.getFileStores();
        List<MachineDiskInfo> machineDiskInfoList = new ArrayList<>();
        for (OSFileStore fs : fsArray) {
            long totalSpace = fs.getTotalSpace();
            long freeSpace = fs.getUsableSpace();
            long usedSpace = totalSpace - freeSpace;
            Double totalSpaceG = 1.0 * totalSpace / GB;
            Double freeSpaceG = 1.0 * freeSpace / GB;
            Double usedSpaceG = 1.0 * usedSpace / GB;
            MachineDiskInfo machineDiskInfo = new MachineDiskInfo();
            machineDiskInfo.setDirName(fs.getMount());
            machineDiskInfo.setTotal(ConvertUtil.convert2Double(totalSpaceG, 1));
            machineDiskInfo.setFree(ConvertUtil.convert2Double(freeSpaceG, 1));
            machineDiskInfo.setUsed(ConvertUtil.convert2Double(usedSpaceG, 1));
            if(totalSpaceG!=0){
                machineDiskInfo.setUseRatio(ConvertUtil.convert2Double(usedSpaceG / totalSpaceG * 100, 2));
            }
            machineDiskInfoList.add(machineDiskInfo);
        }
        return machineDiskInfoList;
    }
}
